<template>
  <div class="rule-tree">
    <div class="rule-tree-content">
      <div
        v-if="children.length > 1"
        class="rule-logic"
      >
        <span @click="logicVal = !logicVal">{{ logicVal | logicFilter }}</span>
      </div>
      <div :class="{'rule-groups':showRuleStyle}">
        <div
          v-for="(child, childIndex) in children"
          :key="childIndex"
          class="rule-group"
        >
          <div class="rule-group-operation">
            <div v-if="showTitle" class="rule-group-expand">
              <svg-icon
                v-if="child[childrenKey].length === 0"
                icon-class="-"
              ></svg-icon>
              <svg-icon
                v-else
                :icon-class="child.visible !== false ? '-' : '+'"
                @click="setDisplayField(child, !child.visible)"
              ></svg-icon>
              <span>{{ child.title }}</span>
            </div>
            <div class="right-group-operations">
              <span
                v-if="disabled!==1&&showAddBtn"
                class="rule-group-add"
                @click="addChildNode(child)"
              >
                <svg-icon icon-class="add"></svg-icon>添加
              </span>
              <slot
                name="rule-group-calc"
                :data="child"
              ></slot>
            </div>
          </div>
          <transition name="slide-fade">
            <global-rule-tree-node
              v-if="child[childrenKey].length"
              v-show="child.visible !== false"
              :node="child"
              :common-indicator-obj="commonIndicatorObj"
              :cascader-options="$data[child.cascaderOptionsType]"
              :unique-child-data="child.uniqueChildData"
              :show-btn-group="showBtnGroup"
              :show-leaf-btn="showLeafBtn"
              :disabled="disabled"
            ></global-rule-tree-node>
          </transition>
        </div>
      </div>
    </div>
    <global-transfer-dialog
      ref="transferDialog"
      :search-type="'cdp'"
      :visible.sync="dialogVisible"
      :transfer-code="transferCode"
      :transfer-value.sync="transferValue"
      :transfer-right-value-obj.sync="transferRightValueObj"
      @goodsInfo="getGoodsInfo"
    ></global-transfer-dialog>
  </div>
</template>

<script>
import commonMixin from "./common-mixin";
import baseDataMixin from "./base-data";
import RuleNodeConfig from "./rule-node-config";
import { transferMixin } from "@/components/TransferDialog/transfer-dialog-mixin"

export default {
  name: 'GlobalRuleTree',
  mixins: [transferMixin, commonMixin, baseDataMixin],
  props: {
    data: {
      type: Object,
      required: true
    },
    showRuleStyle: { // 是否显示rule-group类名
      type: Boolean,
      default: true
    },
    showAddBtn: { // 是否显示添加按钮
      type: Boolean,
      default: true
    },
    showTitle: { // 是否显示标题按钮
      type: Boolean,
      default: true
    },
    showBtnGroup: { // 是否显示新增及删除按钮
      type: Boolean,
      default: true
    },
    showLeafBtn: { // 是否显示新增按钮
      type: Boolean,
      default: true
    },
    nodeTypes: {
      type: Array,
      default: () => ['property', 'behaviour']
    }
  },
  data() {
    const node = this.buildTree();
    return {
      node: node,
      nodeTemplate: this.clone(node)
    };
  },
  computed: {},
  watch: {
    data: {
      handler(val, oldVal) {
        val && val !== oldVal && this.parseData(val);
      },
      immediate: true
    }
  },
  mounted() { },
  methods: {
    // 组装dom基本渲染结构
    buildTree() {
      const { childrenKey } = this;
      const dataSource = {
        property: this.getUserOptions,
        model: this.getModelOptions,
        behaviour: this.getBehaviourOptions
      };
      const children = this.nodeTypes.reduce((arr, type) => {
        if (Object.hasOwnProperty.call(RuleNodeConfig, type)) {
          const data = this.clone(RuleNodeConfig[type]);
          arr.push(Object.assign(data, { type, [childrenKey]: [] }));
          dataSource[type].call(this);
        }
        return arr;
      }, []);
      children.length && this.getCommonIndicator();
      return {
        ...RuleNodeConfig.root,
        [childrenKey]: children
      };
    },
    // 将组装的渲染结构与真正数据进行关联
    // 把一维数据转换成二维数据
    parseData(data) {
      const { childrenKey } = this;
      const node = this.clone(this.nodeTemplate);
      node[childrenKey].forEach((child) => {
        const { type } = child;
        const visibleField = `show${type[0].toUpperCase() + type.slice(1)}`;
        if (!Object.hasOwnProperty.call(data, visibleField)) {
          this.$set(data, visibleField, true);
        }
        if (!Object.hasOwnProperty.call(data, `${type}Arr`)) {
          this.$set(data, `${type}Arr`, []);
        }
        child[childrenKey] = data[`${type}Arr`];
        Object.defineProperty(child, 'visible', {
          get() { return data[visibleField] },
          set(val) { data[visibleField] = val; }
        });
      });
      [node, ...node[childrenKey]].forEach((obj) => {
        const { logicField } = obj;
        if (!Object.hasOwnProperty.call(data, logicField)) {
          this.$set(data, logicField, obj[logicField]);
        }
        Object.defineProperty(obj, logicField, {
          get() { return data[this.logicField] },
          set(val) { data[this.logicField] = val; }
        });
      });
      this.node = node;
      console.log(this.node)
    },
    setDisplayField(node, visible) {
      this.$set(node, 'visible', visible);
    },
    addChildNode(node) {
      const { childrenKey } = this;
      const { childLogicField } = node;
      const child = {
        [childrenKey]: [],
        logicField: childLogicField,
        [childLogicField]: '1'
      };
      this.setDisplayField(node, true);
      node[childrenKey].push(child);
      this.addLeaf(child, node.uniqueChildData);
    }
  }
}
</script>

<style lang="scss" scoped>
@import "./common.scss";
.rule-tree {
  .slotDiv{
  padding-left: 24px;
  cursor: pointer;
  color: #559ff0;
  line-height: 20px;
  min-width: 60px;
  font-size: 14px;
  margin-top: 20px;
  }
  > .rule-tree-content {
    display: flex;
    .rule-groups {
      flex: 1;
      > .rule-group {
        padding: 12px 13px;
        border-radius: 3px;
        border: 1px solid #e0e6ed;
        & + .rule-group {
          margin-top: 16px;
        }
        > .rule-group-operation {
          display: flex;
          justify-content: space-between;
          align-items: center;
          ::v-deep {
            & + .rule-tree-node {
              margin-top: 13px;
            }
          }
          > .rule-group-expand .svg-icon {
            margin-right: 6px;
          }
          > .right-group-operations {
            > .rule-group-add {
              cursor: pointer;
            }
            > * + * {
              margin-left: 18px;
            }
          }
        }
      }
    }
  }
}
.slide-fade-enter-active {
  transition: all 0.4s ease;
}
.slide-fade-leave-active {
  transition: all 0.4s ease;
}
.slide-fade-enter,
.slide-fade-leave-to {
  transform: translateY(-13px);
  opacity: 0;
}
</style>
